package org.uva.streambuilder;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

public class StreamBuilder extends Applet 
    implements MouseListener, MouseMotionListener, KeyListener, Runnable
{

	private static final long serialVersionUID = 1L;
	int width, height;
    int x,y;
    int mx, my;
    int bx = 40, by = 40;
    Image img;
    Image backbuffer;
    Graphics backg;	
    Thread clockThread;

    public void init() {
	width = getSize().width;
	height = getSize().height;
	x = width/2 - bx;
	y = height/2 -by;
	
	this.setBackground(Color.darkGray);
	img = createImage( width, height);
	backbuffer = createImage( width, height);
	backg = backbuffer.getGraphics();
	backg.setColor(Color.darkGray);
	
	setFocusable(true);
	addKeyListener(this);
	requestFocus(true);
	addMouseListener( this );
	addMouseMotionListener( this );
	
	clockThread = new Thread(this);
	clockThread.start();

    }

    public void mouseEntered( MouseEvent e ) {}
    public void mouseExited (MouseEvent e ) {}
    public void mouseClicked( MouseEvent e ) {
	
	repaint();
    }
	
    public void mousePressed ( MouseEvent e ) {
    	for (StreamModule mod : StreamModule.moduleList)
    	{
    		if (mod.isSelectingBox(e) && e.getButton()==MouseEvent.BUTTON3)
    		{
    			if (mod.isSelected)
    				mod.isSelected = false;
    			else
    				mod.isSelected = true;
    		}
    	}
    	refresh();
    }

    public void mouseReleased (MouseEvent e ) {
    	refresh();
    	e.consume();
    }
    public void mouseMoved( MouseEvent e ) {
    	refresh();
    	
    }
    
    public void refresh() {
    	backg.drawImage( img, 0, 0, this);
    	repaint();
    }

    public void mouseDragged( MouseEvent e ) {
    	refresh();
    }

    public void paint( Graphics g ) {
		update( g );
    }
    
    public void update ( Graphics g ) {
    	for (StreamModule module : StreamModule.getModuleList())
		{
			module.draw(backg);
		}
    	g.drawImage(backbuffer, 0, 0, this);
    }
    
    public void keyPressed(KeyEvent e)
    {
    	ArrayList<StreamModule> selectionList = new ArrayList<StreamModule>();
    	int eventCode = e.getKeyCode();
    	for (StreamModule module : StreamModule.moduleList) {
			if (module.isSelected) {
				module.cleanup();
				selectionList.add(module);
			}
		}
    	
    	if (eventCode == KeyEvent.VK_DELETE)
    	{	for (StreamModule module : selectionList)
    		{
    			module.cleanup();
    		}
    		StreamModule.moduleList.removeAll(selectionList);
    	}
    	
    	if (eventCode == KeyEvent.VK_A)
    	{
    		new AverageStreamModule(this, width/2, height/2);
    	}
    	
    	if (eventCode == KeyEvent.VK_T)
    	{
    		new ThresholdStreamModule(this, width/2, height/2);
    	}
    	
    	if (eventCode == KeyEvent.VK_G) {
    		new GeneratingFunctionStreamModule(this, width/2, height/2);
    	}
    	
    	if (eventCode == KeyEvent.VK_C) {
    		new CountingStreamModule(this, width/2, height/2);
    	}
    	
    	if (eventCode == KeyEvent.VK_M) {
    		new MaxStreamModule(this, width/2, height/2);
    	}
    	
    	if (eventCode == KeyEvent.VK_E) {
    		new EWMAStreamModule(this, width/2, height/2);
    	}
    	if (eventCode == KeyEvent.VK_S) {
    		new SinkStreamModule(this, width/2, height/2);
    	}
    	if (eventCode == KeyEvent.VK_D) {
    		new DerivativeStreamModule(this, width/2, height/2);
    	}
    	
    	refresh();
    }
    
    public void keyReleased(KeyEvent e){
 	
    }
    public void keyTyped(KeyEvent e){

    }
    
    public void destroy()
    {
    	clockThread = null;
    }
    
    public void run()
    {
    	while(true){
    		try {
    			refresh();
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    }

}
